﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System;
using System.Collections.Generic;

namespace Lcsoft.Data
{
	/// <summary>
	/// 表示可以惰性初始化的数据缓存。
	/// </summary>
	/// <typeparam name="TKey">缓存的键的类型。</typeparam>
	/// <typeparam name="TValue">缓存的值的类型。</typeparam>
	public sealed class LazyInitCache<TKey, TValue>
	{
		private readonly Dictionary<TKey, Lazy<TValue>> _cacheDictionary = new Dictionary<TKey, Lazy<TValue>>();
		private readonly object _syncRoot = new object();

		/// <summary>
		/// 提取具有指定键的缓存的值。如果该缓存已经存在则返回它的值，如果该缓存不存在则创建具有指定键的新的缓存并返回它的值。
		/// </summary>
		/// <param name="key">指定数据缓存的键。</param>
		/// <param name="producer">指定一个返回值为 TValue 的 Func 委托。</param>
		/// <returns>返回缓存的值。</returns>
		public TValue Fetch(TKey key, Func<TValue> producer)
		{
			Lazy<TValue> cacheItem;

			if (!this._cacheDictionary.TryGetValue(key, out cacheItem))
			{
				lock (this._syncRoot)
				{
					if (!this._cacheDictionary.TryGetValue(key, out cacheItem))
					{
						cacheItem = new Lazy<TValue>(producer);

						this._cacheDictionary.Add(key, cacheItem);
					}
				}
			}

			return cacheItem.Value;
		}
	}
}
